package com.weaver.qfengx.okhttp.body;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.internal.Util;
import okio.BufferedSink;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public abstract class RequestJsonBody extends RequestBody {

    private String jsonContent;
    private byte[] jsonContentBytes;
    private MediaType mediaType;

    public String getJsonContent() {
        return jsonContent;
    }

    public RequestJsonBody(String content, MediaType mediaType) {
        this.jsonContent = content;
        this.mediaType = mediaType;
        Charset charset = StandardCharsets.UTF_8;
        if (mediaType != null) {
            charset = mediaType.charset();
            if (charset == null) {
                charset = StandardCharsets.UTF_8;
                mediaType = MediaType.parse(mediaType + "; charset=utf-8");
            }
        }
        this.jsonContentBytes = content.getBytes(charset);
    }

    public RequestJsonBody(byte[] jsonContentBytes, MediaType mediaType) {
        this.jsonContentBytes = jsonContentBytes;
        this.mediaType = mediaType;
        this.jsonContent = new String(jsonContentBytes, mediaType.charset());
    }

    @Override
    public abstract MediaType contentType();

    public long contentLength() throws IOException {
        return -1L;
    }

    @Override
    public abstract void writeTo(BufferedSink bufferedSink) throws IOException;

    public static RequestJsonBody createBody(MediaType contentType, String content) {
        Charset charset = StandardCharsets.UTF_8;
        if (contentType != null) {
            charset = contentType.charset();
            if (charset == null) {
                charset = StandardCharsets.UTF_8;
                contentType = MediaType.parse(contentType + "; charset=utf-8");
            }
        }

        byte[] bytes = content.getBytes(charset);
        return createBody(contentType, bytes);
    }


    public static RequestJsonBody createBody(MediaType contentType, byte[] content) {
        return createBody(contentType, content, 0, content.length);
    }

    public static RequestJsonBody createBody(final MediaType contentType, final byte[] content, final int offset, final int byteCount) {
        if (content == null) {
            throw new NullPointerException("content == null");
        } else {
            Util.checkOffsetAndCount((long)content.length, (long)offset, (long)byteCount);
            return new RequestJsonBody(content, contentType) {
                public MediaType contentType() {
                    return contentType;
                }

                public long contentLength() {
                    return (long)byteCount;
                }

                public void writeTo(BufferedSink sink) throws IOException {
                    sink.write(content, offset, byteCount);
                }
            };
        }
    }

}
